package com.aterrizar.jsf;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.el.ELContext;
import javax.faces.application.Application;
import javax.faces.application.FacesMessage;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.component.html.HtmlInputHidden;
import javax.faces.component.html.HtmlInputText;
import javax.faces.component.html.HtmlMessage;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.component.html.HtmlPanelGrid;
import javax.faces.context.FacesContext;
import javax.faces.convert.NumberConverter;
import javax.faces.model.SelectItem;

import aterrizar.Avion;
import aterrizar.CategoriaAvion;
import aterrizar.Clase;
import aterrizar.exceptions.ClaseAsientoDuplicadoException;
import aterrizar.exceptions.ClaseAsientoNoExistenteException;
import aterrizar.persistencia.PersistenciaHardcodeFactory;

/**
 * @author Exe
 */
public class AdministrarAvionesBean {

    private HtmlDataTable dataTable;
	private HtmlPanelGrid dataPanel;
    private HtmlInputHidden dataItemId = new HtmlInputHidden();
	private int indice;
	
	private Avion avion;
	private List<Avion> aviones;
	private Long id;
	private String marca;
	private String modelo;
	private Double velocidad;
	private CategoriaAvion categoriaAvion;
	private List<SelectItem> categorias;
	private Map<String, Integer> asientos;
	private Integer cantAsientos;
	private boolean sinComponentes;

	public AdministrarAvionesBean() {
		asientos = new TreeMap<String, Integer>();
		sinComponentes = true;
		indice = -1;
		// Obtengo las Categorias desde el modelo
		categorias = new ArrayList<SelectItem>();
		for (CategoriaAvion categoria : CategoriaAvion.values()) {
			categorias.add(new SelectItem(categoria));
		}
		
		cargar();
	}
	
	private void cargar() {
		aviones = PersistenciaHardcodeFactory.getInstancia().getAviones();
	}
	
	public String crear() {
		/*indice++;
		dataItemId.setValue(new Long(indice));*/
		indice = -1;
		
		marca = null;
		modelo = null;
		velocidad = null;
		categoriaAvion = null;
		
		asientos.clear();
		for (Clase clase : Clase.values()) {
			asientos.put(clase.toString(), null);
		}

		return "editar";
	}

	public String editar() {
		// Obtengo la fila completa
	    /*dataItem = (AvionBean) dataTable.getRowData();
	    dataItemId.setValue(dataItem.getId());*/
		
		indice = dataTable.getRowIndex();
		avion = aviones.get(indice);
		marca = avion.getMarca();
		modelo = avion.getModelo();
		velocidad = avion.getVelocidad();
		categoriaAvion = avion.getCategoriaAvion();
		
		asientos.clear();
		for (Clase clase : Clase.values()) {
			int cant = 0;
			try {
				if (avion.tieneAsientosClase(clase))
					cant = avion.getAsientos(clase).size();
			} catch (ClaseAsientoNoExistenteException e) {
				e.printStackTrace();
			}
			asientos.put(clase.toString(), cant);
		}
	
		return "editar";
	}
	
	public String guardar() {
//		dataItem.setId(Long.valueOf(dataItemId.getValue().toString()));
		
		Avion a = null;
		int total = 0;
		
		if (getVelocidad() <= 0) {
			FacesMessage message = new FacesMessage("La velocidad debe ser mayor que cero.");
			message.setSeverity(FacesMessage.SEVERITY_ERROR);
			FacesContext.getCurrentInstance().addMessage("avionForm:velocidad",message);
			return null;
		}
		
		try {
			a = new Avion(categoriaAvion, getMarca(), getModelo(), getVelocidad());
			
			for (Clase clase : Clase.values()) {
				/* Por alguna razon no funciona esto:
				Integer cant = asientos.get(clase.toString());*/

				Object o = asientos.get(clase.toString());
				Integer cant = Integer.valueOf(o.toString());
				if (cant != null && cant > 0) {
					a.crearAsientos(cant, clase);
					total += cant;
				}
				else if (cant < 0) {
					FacesMessage message = new FacesMessage("La cantidad debe ser mayor que cero.");
					message.setSeverity(FacesMessage.SEVERITY_ERROR);
					FacesContext.getCurrentInstance().addMessage("avionForm:" + clase.toString(),message);
					return null;
				}
			}
		} catch (ClaseAsientoDuplicadoException e) {
			e.printStackTrace();
		}
		
		if (total == 0) {
			FacesMessage message = new FacesMessage("Debe crearse por lo menos un asiento de alguna clase.");
			message.setSeverity(FacesMessage.SEVERITY_ERROR);
			FacesContext.getCurrentInstance().addMessage("avionForm",message);
			return null;
		}
		
		if (indice == -1)
			//aviones.add(a);
			PersistenciaHardcodeFactory.getInstancia().getAviones().add(a);
		else
			//aviones.set(indice, a);
			PersistenciaHardcodeFactory.getInstancia().getAviones().set(indice, a);
		
		//TODO guardar a DAO
		//DAO.guardar(dataItem);
		
		//aviones.add(dataItem);
		cargar();
		return "listar";
	}


	public String listar() {
		return "listar";
	}

	//-------------------------------------
	
	public List<Avion> getAviones() {
		/*if (aviones == null)
			cargar();
*/
		return aviones;
	}

	public void setAviones(List<Avion> aviones) {
		this.aviones = aviones;
	}

	public HtmlDataTable getDataTable() {
		return dataTable;
	}

	public void setDataTable(HtmlDataTable dataTable) {
		this.dataTable = dataTable;
	}

	public Avion getAvion() {
		return avion;
	}

	public void setAvion(Avion avion) {
		this.avion = avion;
	}

	public HtmlInputHidden getDataItemId() {
		return dataItemId;
	}

	public void setDataItemId(HtmlInputHidden dataItemId) {
		this.dataItemId = dataItemId;
	}
	
	//-------------------------------

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getMarca() {
		return marca;
	}

	public void setMarca(String marca) {
		this.marca = marca;
	}

	public String getModelo() {
		return modelo;
	}

	public void setModelo(String modelo) {
		this.modelo = modelo;
	}

	public Double getVelocidad() {
		return velocidad;
	}

	public void setVelocidad(Double velocidad) {
		this.velocidad = velocidad;
	}

	public CategoriaAvion getCategoriaAvion() {
		return categoriaAvion;
	}

	public void setCategoriaAvion(CategoriaAvion categoria) {
		this.categoriaAvion = categoria;
	}

	public List<SelectItem> getCategorias() {
		return categorias;
	}

	public void setCategorias(List<SelectItem> categorias) {
		this.categorias = categorias;
	}

	public java.lang.Integer getCantAsientos() {
/*		if (asientos != null) {
			cantAsientos = new Integer(0);
			for (int i = 0; i < asientos.length; i++) {
				if (asientos[i] != null)
					cantAsientos += asientos[i];
			} 
		}*/
/*		cantAsientos = 0;
		for (Integer asiento : asientos) {
			cantAsientos += asiento;
		}*/
		return cantAsientos;
	}

	public void setCantAsientos(java.lang.Integer cantAsientos) {
/*		cantAsientos = 0;
		for (Integer asiento : asientos) {
			cantAsientos += asiento;
		}*/
		this.cantAsientos = cantAsientos;
	}

	public HtmlPanelGrid getDataPanel() {
		return dataPanel;
	}

	public void setDataPanel(HtmlPanelGrid dataPanel) {
		// Agrego los componentes para la cantidad de asientos de cada clase
		if (dataPanel != null && sinComponentes) {
			Application app = FacesContext.getCurrentInstance().getApplication();
			ELContext EL = FacesContext.getCurrentInstance().getELContext();
		
			// Obtengo las Clases de asiento desde el modelo
			for (Clase laClase : Clase.values()) {
				String clase = laClase.toString();
				
				// Creo un label
				HtmlOutputText text = new HtmlOutputText();
				text.setValue("Cantidad de asientos de clase '" + clase + "'");
				dataPanel.getChildren().add(text);

				// Creo un input
				HtmlInputText text2 = new HtmlInputText();
				text2.setRequired(true);
				text2.setId(clase);
				text2.setRequiredMessage("Requerido");
				String binding = "#{administrarAvionesBean.asientos['" + clase + "']}";
				text2.setValueExpression("value",
					app.getExpressionFactory().createValueExpression(EL, binding, Integer.class));
				NumberConverter conv = new NumberConverter();
				conv.setIntegerOnly(true);
				text2.setConverter(conv);
				dataPanel.getChildren().add(text2);
				
				// Creo un message
				HtmlMessage msg = new HtmlMessage();
				msg.setId("msg_" + clase);
				msg.setErrorClass("error");
				msg.setFor(clase);
				dataPanel.getChildren().add(msg);
			}
			sinComponentes = false;
			this.dataPanel = dataPanel;
		}
	}

	public Map<String, Integer> getAsientos() {
		return asientos;
	}

	public void setAsientos(Map<String, Integer> asientos) {
		this.asientos = asientos;
	}
}
